package net.wicp.tams.commons;

import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Validate;

import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.commons.apiext.ClassLoaderPlugin;
import net.wicp.tams.commons.apiext.IOUtil;

/***
 * 
 * @author 偏锋书生
 *
 */
@Slf4j
public class Plugin {

	private ClassLoaderPlugin load;

	// private final Map<String, String> params;
	private final String subClassName;// "net.wicp.tams.duckula.plugin.IReceive"

	public Plugin(String dirpath, String subClassName, ClassLoader parent) {
		Validate.notBlank(dirpath, "插件所在的路径必须传　");
		load = new ClassLoaderPlugin(dirpath, parent);
		this.subClassName = subClassName;
	}

	public ClassLoaderPlugin getLoad() {
		return load;
	}

	public Class<?> loadReceive(final String... excludes) {
		try {
			Set<String> subs = IOUtil.findSubClassByJars(subClassName, 5, load.getJars(), load.getPool());
			if (ArrayUtils.isNotEmpty(excludes)) {
				CollectionUtils.filter(subs, new Predicate() {
					@Override
					public boolean evaluate(Object object) {
						return !ArrayUtils.contains(excludes, object);
					}
				});
			}
			if (CollectionUtils.isEmpty(subs) || subs.size() > 1) {
				log.error(" {} 存在２个实现类,请检查代码", subClassName);
				throw new IllegalArgumentException("recivers error");
			}
			Class<?> calssz = load.loadClass(subs.iterator().next());
			return calssz;// (IReceive) calssz.newInstance();
		} catch (ClassNotFoundException e) {
			log.info("the recicer is error", e);
			throw new RuntimeException("have no recicer");
		} catch (Exception e) {
			log.info("load receive is error", e);
			throw new RuntimeException("load receive is error");
		}
	}

	public Object newObject(Map<String, String> params, String... excludes) {
		try {
			return loadReceive(excludes).getConstructor(Map.class).newInstance(params);
		} catch (Exception e) {
			log.error("创建object失败", e);
			return null;
		}
	}

	public Object newObject(JSONObject params, String... excludes) {
		try {
			return loadReceive(excludes).getConstructor(JSONObject.class).newInstance(params);
		} catch (Exception e) {
			log.error("创建object失败", e);
			return null;
		}
	}

	public Object newObject(String... excludes) {
		try {
			return loadReceive(excludes).newInstance();
		} catch (Exception e) {
			log.error("创建object失败", e);
			return null;
		}
	}

}
